將 招牌 加入新的 Canvas
import React, { Suspense, useRef, useState } from 'react'
import { Canvas, useFrame, applyProps } from '@react-three/fiber'
import * as THREE from 'three'
import { useLayoutEffect } from 'react'
import { AccumulativeShadows, RandomizedLight, OrbitControls, Environment, useGLTF } from '@react-three/drei'
import { FlakesTexture } from 'three-stdlib'
function Box(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
const ref_spotLight = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => {
// ref.current.rotation.z += delta
ref.current.rotation.x = -0.2
ref.current.rotation.z = 0
ref.current.position.x = 0
ref.current.position.y = 2
})
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
<Suspense fallback={null}>
<GoldenLogo position={[0, 0, -1]} scale={1.5} rotation={[0, Math.PI / 2, Math.PI / 2]} castShadow receiveShadow />
</Suspense>
</mesh>
)
}
function CBLight(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref_spotLight = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
const [r] = useState(() => Math.random() * 10000)
useFrame((_) => (ref_spotLight.current.position.x = -1.75 + Math.sin(_.clock.elapsedTime + r) * 175))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh {...props} ref={ref_spotLight}>
<spotLight angle={1} penumbra={0.5} intensity={0.75} position={[0, 15, 450]} castShadow />
</mesh>
)
}
export default function Logo() {
return (
<Canvas shadows camera={{ position: [0, 2, 10], fov: 25 }}>
<Environment preset="city" />
<color attach="background" args={['#FCF4EE']} />
<ambientLight intensity={0.5} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
<pointLight position={[-10, -10, -10]} />
<pointLight castShadow position={[0, 1, 3]} penumbra={10} />
<Suspense fallback={null}>
<CBLight position={[0, 5, 50]} />
<Box position={[0, 0, 0]} />
</Suspense>
</Canvas>
)
}
export function GoldenLogo(props) {
const { scene, materials } = useGLTF('/元藥堂.gltf')
useLayoutEffect(() => {
scene.traverse((obj) => obj.isMesh && (obj.receiveShadow = obj.castShadow = true))
applyProps(materials.Golden, {
color: 'orange',
roughness: 0,
normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
'normalMap-repeat': [40, 40],
normalScale: [0.05, 0.05]
})
applyProps(materials.TexTboxBase, {
color: '#1C1F1E',
roughness: 0,
normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
'normalMap-repeat': [40, 40],
normalScale: [0.05, 0.05]
})
})
return <primitive object={scene} {...props} />
}
接下來修改背景與照招牌照明的燈光效果
import React, { Suspense, useRef, useState } from 'react'
import { Canvas, useFrame, applyProps } from '@react-three/fiber'
// import GoldenText from './GoldenText'
// import { OrbitControls, Bounds, BakeShadows, Environment, ContactShadows } from '@react-three/drei'
import * as THREE from 'three'
import { useLayoutEffect } from 'react'
import { AccumulativeShadows, RandomizedLight, OrbitControls, Environment, useGLTF } from '@react-three/drei'
import { FlakesTexture } from 'three-stdlib'
function Box(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
const ref_spotLight = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => {
// ref.current.rotation.z += delta
ref.current.rotation.x = -0.2
ref.current.rotation.z = 0
ref.current.position.x = 0
ref.current.position.y = 2
})
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
{/* <boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} /> */}
<Suspense fallback={null}>
{/* <GoldenLogo position={[0, 0, -1]} scale={1.5} rotation={[0, Math.PI / 2, Math.PI / 2]} castShadow receiveShadow /> */}
<GoldenLogo position={[0, 0, -1]} scale={1.5} rotation={[0, Math.PI / 2, Math.PI / 2]} castShadow receiveShadow />
</Suspense>
</mesh>
)
}
function CBLight(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref_spotLight = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
// useFrame((state, delta) => {
// // ref.current.rotation.z += delta
// // ref.current.rotation.x = -0.2
// // ref.current.rotation.z = 0
// // ref.current.position.x = 0
// ref_spotLight.current.position.x += delta * 10
// })
const [r] = useState(() => Math.random() * 10000)
useFrame((_) => (ref_spotLight.current.position.x = -1.75 + Math.sin(_.clock.elapsedTime + r) * 175))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh {...props} ref={ref_spotLight}>
<spotLight angle={1} penumbra={0.5} intensity={0.75} position={[0, 15, 450]} castShadow />
</mesh>
)
}
export default function Logo() {
return (
<Canvas shadows camera={{ position: [0, 2, 10], fov: 25 }}>
{/* sunset: string;
dawn: string;
night: string;
warehouse: string;
forest: string;
apartment: string;
studio: string;
city: string;
park: string;
lobby: string; */}
<Environment preset="night" />
{/* <color attach="background" args={['#FCF4EE']} /> */}
{/* <ambientLight intensity={1} /> */}
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
<pointLight position={[-10, -10, -10]} />
<pointLight castShadow position={[0, 1, 3]} penumbra={10} />
<Suspense fallback={null}>
<CBLight position={[0, 5, 50]} />
<Box position={[0, 0, 0]} />
</Suspense>
{/* <Suspense fallback={null}>
<GoldenText position={[0, 2, 0]} scale={1.5} rotation={[0, Math.PI / 2, Math.PI / 2]} castShadow receiveShadow />
</Suspense> */}
</Canvas>
)
}
export function GoldenLogo(props) {
const { scene, materials } = useGLTF('/元藥堂.gltf')
// const { scene, materials } = useGLTF('https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/models/suzanne-high-poly/model.gltf')
useLayoutEffect(() => {
scene.traverse((obj) => obj.isMesh && (obj.receiveShadow = obj.castShadow = true))
applyProps(materials.Golden, {
color: 'orange',
roughness: 0,
normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
'normalMap-repeat': [40, 40],
normalScale: [0.05, 0.05]
})
applyProps(materials.TexTboxBase, {
color: '#1C1F1E',
roughness: 0,
normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
'normalMap-repeat': [40, 40],
normalScale: [0.05, 0.05]
})
// applyProps(materials.insideBase, {
// color: 'FFBD33',
// roughness: 0,
// normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
// 'normalMap-repeat': [40, 40],
// normalScale: [0.05, 0.05]
// })
})
return <primitive object={scene} {...props} />
}